﻿//================================================================================
// Filename: MessageBoardPlugin.as
// Authour: Jacky Fong
// Description:
// Message board
//
// Input Events
// - MessageBoardPlugin_SetPage
// - MessageBoardPlugin_Connect
// - MessageBoardPlugin_BrowseHeader
// - MessageBoardPlugin_ReadMessage
//
// Output Events
//
// Listening to other Events
//================================================================================

package
{
    import flash.display.Loader;
	import flash.display.Stage;
    import flash.net.URLRequest;
	import flash.net.URLLoader;
	import flash.net.Responder;
	import flash.net.NetConnection;
	import flash.net.ObjectEncoding;
	import flash.display.Sprite;
	import flash.display.DisplayObjectContainer;
	import flash.display.MovieClip;	
	import flash.events.*;	
	import IPlugin;
	import PluginManager;
	import PluginEvent;	
	
	public class MessageBoardPlugin extends Sprite implements IPlugin
	{
		private static const _pluginName:String = "MessageBoardPlugin";
		private var _manager:PluginManager;
		private var _container:Sprite;
		private var _memoContainer:Sprite;
		private var _bigMemoRead:MovieClip;
		private var _bigMemoWrite:MovieClip;
		private var _btnNext:MovieClip;
		private var _btnPrevious:MovieClip;
		private var _nc:NetConnection;
		private var _uiLib:Object;
		
		// properties
		// todo: read from xml
		private var _bigMemoX:int = 500;
		private var _bigMemoY:int = 180;
		private var _memoStartX:int = 50;
		private var _memoStartY:int = 200;
		private var _btnPreviousX:int = 180;
		private var _btnPreviousY:int = 620;		
		private var _btnNextX:int = 250;
		private var _btnNextY:int = 620;
		private var _memoSize:uint = 100;
		private var _maxCol:uint = 4;
		private var _varPos:Number = 15;
		private var _maxMemo:uint = 16;
		
		function MessageBoardPlugin()
		{
			init();
		}
		
		public function get pluginName():String
		{
			return _pluginName;
		}
		
		public function init():void
		{
			trace( "Init " + _pluginName );
			_container = new Sprite();
			_memoContainer = new Sprite();
			_container.addChild( _memoContainer );
		}		

		public function setManager( manager:PluginManager ):void
		{
			_manager = manager;
			_loadUI( "ui/MessageBoard.swf" );
			_setupEventListeners();
		}
		
		private function _setupEventListeners():void
		{
			if( _manager == null ) return;
			
			_manager.addEventListener( "MessageBoardPlugin_SetPage", _onSetPage );
			_manager.addEventListener( "MessageBoardPlugin_Connect", _onConnect );
			_manager.addEventListener( "MessageBoardPlugin_BrowseHeader", _onBrowseHeader );
			_manager.addEventListener( "MessageBoardPlugin_ReadMessage", _onReadMessage );
		}		

		//=====================================================================
		private function _loadUI( url:String ):void
		{
			var loader:Loader = new Loader();
			loader.contentLoaderInfo.addEventListener( Event.COMPLETE, _loadUIComplete );			
			loader.contentLoaderInfo.addEventListener( IOErrorEvent.IO_ERROR, _loadUIIoError );
            var req:URLRequest = new URLRequest( url );
            loader.load( req );
		}
		
		private function _loadUIComplete( evt:Event ):void
		{
			_manager.apiLog( this + " LoadUIComplete: " + evt );
			_uiLib = evt.target.content;
			
			_bigMemoRead = new _uiLib.MessageBoardBigMemoRead();
			_bigMemoRead.x = _bigMemoX;
			_bigMemoRead.y = _bigMemoY;
			_container.addChild( _bigMemoRead );
			
			_bigMemoWrite = new _uiLib.MessageBoardBigMemoWrite();
			_bigMemoWrite.visible = false; // default hidden
			_bigMemoWrite.x = _bigMemoX;
			_bigMemoWrite.y = _bigMemoY;
			_container.addChild( _bigMemoWrite );
			
			_bigMemoRead.mcWriteMsgTip.visible = false;
			_setBigMemoLink();
			
			_btnNext = new _uiLib.MessageBoardNextButton();
			_btnNext.x = _btnNextX;
			_btnNext.y = _btnNextY;
			_btnNext.visible = false; // temp
			_container.addChild( _btnNext );
			_btnPrevious = new _uiLib.MessageBoardPreviousButton();
			_btnPrevious.x = _btnPreviousX;
			_btnPrevious.y = _btnPreviousY;
			_btnPrevious.visible = false; // temp
			_container.addChild( _btnPrevious );
			_setHeaderButtonsLinks();
		}

		private function _loadUIIoError( evt:IOErrorEvent ):void
		{
			_manager.apiLog( this + " LoadUIIoError: " + evt );
		}
		
		//=====================================================================
		private function _testServices():void
		{
			// start calling service
			var responder:Responder;
			//responder = new Responder( _onWriteMsgResult, _onFault );
			//_nc.call( "MessageService.writeMsg", responder, "hello", "ff", "", "" );
			
			responder = new Responder( _onReadMsgResult, _onFault );
			_nc.call( "MessageService.readMsg", responder, 1 );
			
			responder = new Responder( _onBrowseMsgResult, _onFault );			
			_nc.call( "MessageService.browseMsg", responder, -1, -1 );
			
			responder = new Responder( _onBrowseHeaderResult, _onFault );
			_nc.call( "MessageService.browseHeader", responder, -1, -1 );
		}
		
		private function _readMessage( id:int ):void
		{
			var responder:Responder = new Responder( _onReadMsgResult, _onFault );
			_nc.call( "MessageService.readMsg", responder, id );
		}
		
		private function _browseHeader( startId:int, nMsg:int ):void
		{
			var responder:Responder = new Responder( _onBrowseHeaderResult, _onFault );
			_nc.call( "MessageService.browseHeader", responder, startId, nMsg );
			_manager.dispatchEvent( new PluginEvent( "LoadingProgressPlugin_Show", { show:true } ) );
		}
		
		private function _writeMessage( body:String, authour:String, email:String, url:String ):void
		{
			var responder:Responder = new Responder( _onWriteMsgResult, _onFault );
			_nc.call( "MessageService.writeMsg", responder, body, authour, email, url );			
		}
		
		private function _onWriteMsgResult( result:Object ):void
		{
			_manager.apiLog( "WriteMsg Result: " + result );
			// return to read message, update new memos
			_showBigMemo( true );
			_browseHeader( -1, _maxMemo );
			_readMessage( -1 );
		}
		
		private function _onReadMsgResult( result:Object ):void
		{
			_manager.apiLog( "ReadMsg Result: " + result );
			if( result[0] <= 0 || result.length <= 1 ) return;

			trace( "Id: " + result[1][0] );
			trace( "Date: " + result[1][1] );
			trace( "Authour: " + result[1][2] );
			trace( "Email: " + result[1][3] );
			trace( "Url: " + result[1][4] );
			trace( "Body: " + result[1][5] );
			
			_bigMemoRead.txtDate.text = result[1][1];
			_bigMemoRead.txtAuthour.text = result[1][2];
			_bigMemoRead.txtUrl.text = result[1][4];
			_bigMemoRead.txtBody.text = result[1][5];
		}
		
		private function _onBrowseMsgResult( result:Object ):void
		{
			_manager.apiLog( "BrowseMsg Result: " + result );
			if( result[0] <= 0 ) return;

			for( var i=1; i<result.length; i++ ) {
				trace( "Id: " + result[i][0] );
				trace( "Date: " + result[i][1] );
				trace( "Authour: " + result[i][2] );
				trace( "Email: " + result[i][3] );
				trace( "Url: " + result[i][4] );
				trace( "Body: " + result[i][5] );
			}
		}
		
		private function _onBrowseHeaderResult( result:Object ):void
		{
			_manager.dispatchEvent( new PluginEvent( "LoadingProgressPlugin_Show", { show:false } ) );
			
			_manager.apiLog( "BrowseHeader Result: " + result );
			if( result[0] <= 0 ) return;

			_removeDisplayObjectContainerChildren( _memoContainer );
			
			for( var i=1; i<result.length; i++ ) {
				trace( "Id: " + result[i][0] );
				trace( "Date: " + result[i][1] );
				trace( "Authour: " + result[i][2] );
				
				var nImage:int = i - 1;
				var ranMemo:uint = _rangeRandom( 1, 3 );
				var memo:MovieClip;
				switch( ranMemo ) {
					case 1: memo = new _uiLib.MessageBoardMemo1(); break;
					case 2: memo = new _uiLib.MessageBoardMemo2(); break;
					case 3: memo = new _uiLib.MessageBoardMemo3(); break;
				}				
				memo.x = _memoStartX + int( nImage % _maxCol ) * _memoSize + _rangeRandom( 0, _varPos );
				memo.y = _memoStartY + int( nImage / _maxCol ) * _memoSize + _rangeRandom( 0, _varPos );
				memo.txtName.text = result[i][2];
				var str:String = result[i][1];
				var pattern:RegExp = / /;
				memo.txtDate.text = str.replace( pattern, "\r" );

				_setMemoLink( memo, result[i][0] );				
				_memoContainer.addChild( memo );				
			}
		}
		
		private function _setMemoLink( memo:MovieClip, id:int ):void
		{
			var func:Object = new Object();
			func.onMouseClick = function( evt:MouseEvent )
			{
				_readMessage( id );
			}
			func.onMouseOver = function( evt:MouseEvent )
			{
			}
			func.onMouseOut = function( evt:MouseEvent )
			{
			}			
			memo.addEventListener( MouseEvent.CLICK, func.onMouseClick );
			memo.addEventListener( MouseEvent.MOUSE_OVER, func.onMouseOver );
			memo.addEventListener( MouseEvent.MOUSE_OUT, func.onMouseOut );			
		}
		
		private function _setBigMemoLink():void
		{
			var funcWriteMsg:Object = new Object();
			funcWriteMsg.onMouseClick = function( evt:MouseEvent )
			{
				_bigMemoWrite.txtBody.text = "";
				_bigMemoWrite.txtAuthour.text = "";
				_bigMemoWrite.txtEmail.text = "";
				_bigMemoWrite.txtUrl.text = "";
				
				_showBigMemo( false );
			}
			funcWriteMsg.onMouseOver = function( evt:MouseEvent )
			{
				_bigMemoRead.mcWriteMsgTip.visible = true;
			}
			funcWriteMsg.onMouseOut = function( evt:MouseEvent )
			{
				_bigMemoRead.mcWriteMsgTip.visible = false;
			}			
			_bigMemoRead.mcWriteMsg.addEventListener( MouseEvent.CLICK, funcWriteMsg.onMouseClick );
			_bigMemoRead.mcWriteMsg.addEventListener( MouseEvent.MOUSE_OVER, funcWriteMsg.onMouseOver );
			_bigMemoRead.mcWriteMsg.addEventListener( MouseEvent.MOUSE_OUT, funcWriteMsg.onMouseOut );
			
			var funcSubmit:Object = new Object();
			funcSubmit.onMouseClick = function( evt:MouseEvent )
			{
				_writeMessage( _bigMemoWrite.txtBody.text, _bigMemoWrite.txtAuthour.text,
							   _bigMemoWrite.txtEmail.text, _bigMemoWrite.txtUrl.text );
			}
			_bigMemoWrite.mcSubmit.addEventListener( MouseEvent.CLICK, funcSubmit.onMouseClick );
			
			var funcCancel:Object = new Object();
			funcCancel.onMouseClick = function( evt:MouseEvent )
			{
				_showBigMemo( true );
			}
			_bigMemoWrite.mcCancel.addEventListener( MouseEvent.CLICK, funcCancel.onMouseClick );						
		}
		
		private function _setHeaderButtonsLinks():void
		{
			var funcPrev:Object = new Object();
			funcPrev.onMouseClick = function( evt:MouseEvent )
			{
				_manager.apiLog( "Previous Button Click" );
			}
			_btnPrevious.addEventListener( MouseEvent.CLICK, funcPrev.onMouseClick );
			
			var funcNext:Object = new Object();
			funcNext.onMouseClick = function( evt:MouseEvent )
			{
				_manager.apiLog( "Next Button Click" );
			}
			_btnNext.addEventListener( MouseEvent.CLICK, funcNext.onMouseClick );
		}
		
		// toggle between read and write memo
		private function _showBigMemo( isRead:Boolean ):void
		{
			if( isRead ) {
				_bigMemoRead.visible = true;
				_bigMemoWrite.visible = false;				
			}
			else {
				_bigMemoRead.visible = false;
				_bigMemoWrite.visible = true;				
			}
		}
		
		// common fault handler
		private function _onFault( fault:Object ):void
		{
			_manager.apiLog( "onFault: " + fault );
			for( var f in fault ) {
				trace( f + ": " + fault[f] );
			}
		}
		
		//==========================================================================
		// helpers
		//==========================================================================
		// remove all children from a DisplayObjectContainer
		private function _removeDisplayObjectContainerChildren( container:DisplayObjectContainer ):void
		{
			var children:Array = new Array();
			for( var i:uint=0; i<container.numChildren; i++ ) {
				children.push( container.getChildAt( i ) );
			}
			for( i=0; i<children.length; i++ ) {
				container.removeChild( children[i] );
			}			
		}
		
		private function _rangeRandom( min:Number, max:Number ):Number
		{
			return ( min + Math.random() * ( max - min + 1 ) );
		}
		
		//==========================================================================
		// plugin API
		//==========================================================================
		private function _onSetPage( evt:PluginEvent ):void
		{
			_manager.apiLog( this + " _onSetPage: " + evt );
			
			_manager.dispatchEvent( new PluginEvent( "PagePlugin_AddPageDisplayObjectContainer", { page:evt.args.page, container:_container } ) );
		}
		
		private function _onConnect( evt:PluginEvent ):void
		{
			_manager.apiLog( this + " _onConnect: " + evt );
			
			_nc = new NetConnection();
//			_nc.objectEncoding = ObjectEncoding.AMF0;
			_nc.connect( evt.args.url );			
		}
		
		private function _onBrowseHeader( evt:PluginEvent ):void
		{
			_manager.apiLog( this + " _onBrowseHeader: " + evt );
			_browseHeader( evt.args.startId, evt.args.nMsg );
		}
		
		private function _onReadMessage( evt:PluginEvent ):void
		{
			_manager.apiLog( this + " _onReadMessage: " + evt );
			_readMessage( evt.args.id );
		}		
	}
}